"""
Copyright 2009, Thomas Dejanovic, Jay Shurtz.
 
This is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of
the License, or (at your option) any later version.

This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this software; if not, write to the Free
Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301 USA, or see the FSF site: http://www.fsf.org.

This module exists to define constants used throughout hatch.
"""
 
#----------------------------------------------------------------------

id = "$Id: hatch_constants.py 717 2010-09-10 07:07:33Z jayshurtz $"
# $URL: http://hatch.googlecode.com/svn/tags/taggle_release_3.0/hatch/hatch_library/hatch_constants.py $
# $Author: jayshurtz $
version = " ".join(id.split()[1:3])

#----------------------------------------------------------------------

# Hatch global definitions.
FILE_NAME = 'hatchFileName' # The name of the file that stores 'this' hatch design.  This is (automatically) applied ONLY to the top node in the file (see hatch_files.py.)
TOP_NODE = 'hatchBlock' # The top level node in a hatch design file MUST have this name. XXX change this to 'module' ?

MAX_DATA_BUS_WIDTH = 32 # Data bus is max 1 word wide (32 bits).
DATA_BUS_WIDTH = MAX_DATA_BUS_WIDTH
MAX_WIDTH_BITS = MAX_DATA_BUS_WIDTH

#----------------------------------------------------------------------

# Hatch node class attributes.  These values should not change.
NAME_ATTRIBUTE = 'name'
PARENT_ATTRIBUTE = 'parent'
PROPERTIES_ATTRIBUTE = 'properties'
CHILDNODES_ATTRIBUTE = 'childNodes'
HATCH_NODE_ATTRIBUTES = set([NAME_ATTRIBUTE, PARENT_ATTRIBUTE, PROPERTIES_ATTRIBUTE, CHILDNODES_ATTRIBUTE])

# Hatch interface class attributes.  
HATCH_INTERFACE_ATTRIBUTES = set() | HATCH_NODE_ATTRIBUTES
HATCH_INTERFACE_ATTRIBUTES |= set(['hatchInterface', 'nodesMap', 'topNode', 'delimiter', 'publicAttributes'])
HATCH_INTERFACE_ATTRIBUTES |= set(['ITERATE_MESSAGE', 'IMMUTABLE_ITEMS_MESSAGE'])
HATCH_INTERFACE_ATTRIBUTES |= set(['put', 'get', 'read', 'write'])
HATCH_INTERFACE_ATTRIBUTES |= set(['__init__', '__dir__', '__getattr__', '__setattr__', '__delattr__'])
HATCH_INTERFACE_ATTRIBUTES |= set(['hatchFacade', '__str__', 'depthFirst', 'breadthFirst'])
HATCH_INTERFACE_ATTRIBUTES |= set(['readIterative', 'writeIterative', 'readDepthFirst',])
HATCH_INTERFACE_ATTRIBUTES |= set(['writeDepthFirst', 'readBreadthFirst', 'writeBreadthFirst'])
HATCH_INTERFACE_ATTRIBUTES |= set(['__call__', '__len__', '__iter__', '__contains__', '__getitem__', '__setitem__', '__delitem__'])
HATCH_INTERFACE_ATTRIBUTES |= set(['__module__', '__reduce_ex__', '__new__', '__reduce__'])
HATCH_INTERFACE_ATTRIBUTES |= set(['__getattribute__', '__class__', '__hash__', '__repr__'])
HATCH_INTERFACE_ATTRIBUTES |= set(['__dict__', 'IMMUTABLE_ATTRIBUTES_MESSAGE', '__weakref__'])
HATCH_INTERFACE_ATTRIBUTES |= set(['__doc__', 'IteratorBreadthFirst', 'IteratorDepthFirst'])

# Illegal names for hatch nodes.  It does not break hatch if nodes do have
# these names, but the hatch interface will not be able to access that node
# in a normal fashion.  Empty string is not allowed.
ILLEGAL_NAMES = set([""]) | HATCH_INTERFACE_ATTRIBUTES | HATCH_NODE_ATTRIBUTES

#----------------------------------------------------------------------

# Hatch node instance properties: 

# Format types.
XML = 'xml' # XML property used to define a hatch node. Removed & converted to python before hatching by hatch_format_translator.py.
RTL = 'rtl' # RTL property used to define 'register transfer level' details.  Converted to target format when hatching.

# Node types.
HATCH_LEAF = 'hatch_leaf'   # True for leaf nodes that are not supposed to have child nodes, False for block nodes that must have child nodes. Set by class.
PACKED = 'packed'   # True any node sharing the bits of an address with another node. Set by the address mapper.  # TODO change this to 'IS_IN_A_PACK' XXX Don't assign this to packs in the address mapper!!
DEFAULT_VALUE = 'default'   # Default value for a leaf. Defaults to zero in hatch_register.py.

# Visitors / Targets.
GLOBAL_NAME = 'global_name' # Globally unique name for a hatch node in a design. Generated by hatch_property_elaborator.py.
#LOCAL_NAME = 'local_name'   # Locally unique name. (Local scope is defined as fellow child nodes within parent.)


# Documentation
COMMENT = 'comment' # Comment property of a node. Fleshed out by the info elaborator.


# interface commands.
AUX_WRITE_COMMAND = 'write_command'
AUX_READ_COMMAND  = 'read_command'

# Hardware address
PACKABLE = 'packable'   # True of any node that is small enough to fit it's child nodes into the bits of a single address. TODO change this to 'IS_A_PACK' ?
BASE_BIT = 'base_bit'   #
BIT_WIDTH = 'bit_width' # Width in bits of a hatch node.
BASE_ADDRESS = 'base_address'   # Global physical base address of a hatch node.
LOCAL_ADDRESS = 'local_address' #
ADDRESS_RANGE = 'local_address_range' # TODO 'address_width' ? 


# Access modes.
SOFTWARE_ACCESS = 'sw'  # Software register access for read/writes. Set by user.
HARDWARE_ACCESS = 'hw'  # Hardware register access for read/writes. Set by user.
AUTOMATIC_ACCESS = 'auto'   # Automatic register actions. Set by user.
ACCESS_MODES = set([SOFTWARE_ACCESS, HARDWARE_ACCESS, AUTOMATIC_ACCESS])    # Register access modes. Values propagated/OR'd down in hatch_property_propagator.py.

# External Access mode.
EXTERNAL = 'external'   # Everything for this node is implemented externally.
EXTERNAL_COMPATIBLE = set([EXTERNAL, SOFTWARE_ACCESS])   # All properties that are compatible with external access.
EXTERNAL_COMPATIBLE |= set([BIT_WIDTH, DEFAULT_VALUE, HATCH_LEAF, PACKED])


# This is documented at char not in "disctp" http://code.google.com/p/hatch/wiki/AutoRegisterAccessModes
# Access mode values. 
READ_ACCESS = 'r'   # TODO - comment these.
WRITE_ACCESS = 'w'
INCREMENT_ACCESS = 'i'
DECREMENT_ACCESS = 'd'
SET_ACCESS = 's'
CLEAR_ACCESS = 'c'
PRESET_ACCESS = 'p'
ACCESS_VALUES = set([READ_ACCESS, WRITE_ACCESS, INCREMENT_ACCESS, DECREMENT_ACCESS])
ACCESS_VALUES |= set([SET_ACCESS, CLEAR_ACCESS, PRESET_ACCESS])


SOFTWARE_ACCESS_VALUES = set([READ_ACCESS, WRITE_ACCESS, SET_ACCESS, CLEAR_ACCESS]) # XXX
SOFTWARE_ACCESS_VALUES = ACCESS_VALUES - set([READ_ACCESS, WRITE_ACCESS])   # XXX same as above ?
HARDWARE_ACCESS_VALUES = ACCESS_VALUES




# Automatic expressions.
AUTOMATIC_CLEAR_EXPRESSION = 'auto_clear_on' # Expression evaluated to automatically clear a register. Set by user.
AUTOMATIC_SET_EXPRESSION = 'auto_set_on' # Expression evaluated to automatically set a register. Set by user.
AUTOMATIC_PRESET_EXPRESSION = 'auto_preset_on'   # Expression evaluated to automatically preset a register. Set by user.
AUTOMATIC_TRIGGER_EXPRESSION = 'auto_trigger_on' # Expression evaluated to automatically trigger a register. Set by user.
AUTOMATIC_INCREMENT_EXPRESSION = 'auto_inc_on'  # Expression evaluated to automatically increment a register. Set by user.
AUTOMATIC_DECREMENT_EXPRESSION = 'auto_dec_on'  # Expression evaluated to automatically decrement a register. Set by user.
AUTOMATIC_ACCESS_EXPRESSIONS = set([AUTOMATIC_CLEAR_EXPRESSION, AUTOMATIC_SET_EXPRESSION])
AUTOMATIC_ACCESS_EXPRESSIONS |= set([AUTOMATIC_PRESET_EXPRESSION, AUTOMATIC_TRIGGER_EXPRESSION])
AUTOMATIC_ACCESS_EXPRESSIONS |= set([AUTOMATIC_INCREMENT_EXPRESSION, AUTOMATIC_DECREMENT_EXPRESSION])


# ???
TRIGGER_COUNT = 'trigger_count' # Number of clock cycles for which a signal will be active. Set by user.


# Propagated properties.
PROPAGATE_FLAG = 'propagate'    # Flag for propagating properties. Set by user, usually defaults to False. Should not be propagated!
PROPAGATED_ACCESS_MODES = ACCESS_MODES  # Access modes normally propagated to child nodes.
PROPAGATED_ACCESS_EXPRESSIONS = set([TRIGGER_COUNT]) | AUTOMATIC_ACCESS_EXPRESSIONS  # Expressions propagated down if not in child node in hatch_property_propagator.py.
# set of properties that are always propagated.
PROPAGATED_PROPERTIES = set([AUX_WRITE_COMMAND, AUX_READ_COMMAND])


# Soft error checking (radiation hardening.)
ERROR_DETECT = 'auto_error_detect'  # Bits of error detection.
ERROR_CORRECT = 'auto_error_correct'    # Bits of error correction.
TARGET_BUS_TYPE = 'target'  # Top node in a design has to have this property so that we can communicate with the hatched design.


# TODO Keyed registers.
TRIGGER_KEY_VALUE = 'trigger_key_value'
AUTO_TRIGGER_VALUE = 'auto_trigger_value'
SW_LOAD_ENABLE = 'sw_load_enable'


# Hatch interface constants.
INVISIBLE = 'invisible' # Hatch Facade Node is invisible to the user. Any Child nodes are seen as children of this node's parent. Very useful for packed registers.


#----------------------------------------------------------------------
#
# Verilog Constants
#

VERILOG_FILE_HEADER = """/*----------------------------------------------------------------------
 *
 * THIS IS A GENERETED FILE - DO NOT EDIT!
 *
 * This file is generated by hatch - http://code.google.com/p/hatch/
 *
 * Hatch is a tool for developing a register interface for FPGAs and ASICs.
 * 
 * */\n\n"""

